#coding:utf8
#
# Author: TooNTonG
# Created on 2010-2-25
#
'''
协议相关, xml与pyDict的双向解释器
'''

import xml.etree.ElementTree
#from xml.parsers.expat import ExpatError
#from django.http import HttpResponse

__all__ = [
    'makeResult',
    'xmlParser'
]

XML_FORMAT = u'''<?xml version="1.0" encoding="utf-8" ?><xLive result="%s">%s</xLive>'''
NODE_FORMAT = u'<%s>%s</%s>'

class XmlDict():
    '''xml与pydict的双向解释器'''
    def __parserXmlData(self, data):
        if not isinstance(data, unicode):
            data = data.decode('utf8')
        data = data.replace(u'&', u'&amp;')
        data = data.replace(u'<', u'&lt;')
        data = data.replace(u'>', u'&gt;')
        return data

    def __objectToXml(self, obj, parent):
        sourceStr = u""
        parent = self.__parserXmlData(parent)
        if isinstance(obj, dict):
            for (key, value) in obj.iteritems():
                resStr = self.__objectToXml(value, key)
                sourceStr = sourceStr + resStr
            if parent:
                return NODE_FORMAT % (parent, sourceStr, parent)
            return sourceStr
        if isinstance(obj, list):
            for value in obj:
                sourceStr = sourceStr + self.__objectToXml(value, parent)
            if not(obj):
                return NODE_FORMAT % (parent, sourceStr, parent)
#            if parent:
#                return NODE_FORMAT % (parent, sourceStr, parent)
            return sourceStr
        if parent:
            return NODE_FORMAT % (parent, self.__parserXmlData(obj) , parent)
        else:
            return self.__parserXmlData(obj)

    def __dictAddItem(self, obj, key, value):
        if value is None:
            value = u''
        if isinstance(value, (str, unicode)):
            value = value.strip() #如果是字符串,去掉两边空格
        if obj.has_key(key):
            if type(obj[key]) != list:
                obj[key] = [obj[key]]
            obj[key].append(value)
        else:
            obj[key] = value

    def __convertPyObj(self, xmlObj):
        res = {}
        for item in xmlObj:
            child = item.getchildren()
            if child:
                self.__dictAddItem(res, item.tag, self.__convertPyObj(child))
            else:
                self.__dictAddItem(res, item.tag, item.text)
        return res

    def __xmlToPyDict(self, xmlNodes):
        '''
        @param xmlParamsStr: XLive Format's XML string
        @return: Dict Object.
        @todo: XML数据格式,解释成py的字兄1�7
        '''
        result = {}
        for item in xmlNodes:
            child = item.getchildren()
            if child:
                self.__dictAddItem(result, item.tag, self.__convertPyObj(child))
            else:
                self.__dictAddItem(result, item.tag, item.text)
        return result

    def xmlGenerater(self, code, data = {}):
        '''
        @param code: Result Code String.
        @param data: Return Data as String Object. 
        @return: 返回 一个xml格式的字符串.
        '''
        result = self.__objectToXml(data, '')
        return XML_FORMAT % (code, result)

    def xmlParser(self, xmlStr):
        '''
        @param xmlStr: XML String. 
        @return: 返回 一个PyDict格式的字符串.
        '''
        if not xmlStr:
            return {}
        xmlRoot = xml.etree.ElementTree.fromstring(xmlStr)
        return {xmlRoot.tag: self.__xmlToPyDict(xmlRoot)}

_xmldict = XmlDict()

#方法重命名,给外层调用
makeResult = _xmldict.xmlGenerater
xmlParser = _xmldict.xmlParser
xmlGenerater = _xmldict.xmlGenerater

if __name__ == '__main__':
    pass
